| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- "use client";
- import { useEffect, useState } from "react";
- import { useTranslations } from "next-intl";
- import { Link } from "@/i18n/navigation";
- import { useAuth } from "@/providers/auth-provider";
- import { History, ArrowLeft, Loader2 } from "lucide-react";
- import {
- fetchWithdrawalList,
- getWithdrawalStatusLabel,
- type WithdrawalRecord,
- } from "@/lib/withdrawal-api";
- import { cn } from "@/lib/utils";
- const PAGE_SIZE = 10;
- export default function AccountWithdrawalsPage() {
- const t = useTranslations("account");
- const { user, isReady } = useAuth();
- const [records, setRecords] = useState<WithdrawalRecord[]>([]);
- const [loading, setLoading] = useState(false);
- const [error, setError] = useState<string | null>(null);
- const [page, setPage] = useState(1);
- useEffect(() => {
- if (!user) return;
- let cancelled = false;
- async function loadRecords() {
- setLoading(true);
- setError(null);
- try {
- const list = await fetchWithdrawalList({ current: page, row: PAGE_SIZE });
- if (cancelled) return;
- setRecords(list);
- } catch (e) {
- if (cancelled) return;
- setError((e as Error).message || "领取记录加载失败,请稍后重试。");
- setRecords([]);
- } finally {
- if (!cancelled) setLoading(false);
- }
- }
- void loadRecords();
- return () => { cancelled = true; };
- }, [user, page]);
- if (!isReady) return <div className="min-h-screen bg-[#050b14] flex items-center justify-center text-slate-500"><Loader2 className="animate-spin" /></div>;
- if (!user) {
- return (
- <div className="min-h-screen bg-[#050b14] flex items-center justify-center px-4 font-sans">
- <div className="w-full max-w-md rounded-[2.5rem] border border-white/10 bg-white/5 p-10 text-center backdrop-blur-2xl">
- <h2 className="text-2xl font-bold text-white mb-6">您尚未登录</h2>
- <Link href="/auth/login" className="inline-block rounded-full bg-[#f3deae] px-10 py-4 text-sm font-bold text-[#5c461a] shadow-lg">立即登录</Link>
- </div>
- </div>
- );
- }
- const hasPrev = page > 1;
- const hasNext = records.length >= PAGE_SIZE;
- function getStatusStyle(status: number | string) {
- const s = String(status);
- if (s === "2" || s === "3") return "text-emerald-400 border-emerald-400/30 bg-emerald-400/10";
- if (s === "4" || s === "5") return "text-rose-400 border-rose-400/30 bg-rose-400/10";
- return "text-amber-400 border-amber-400/30 bg-amber-400/10";
- }
- return (
- <div className="min-h-screen bg-[#050b14] pb-24 text-slate-300 font-sans relative">
- <div className="pointer-events-none fixed inset-0 z-0">
- <div className="absolute left-1/4 top-0 h-[500px] w-[500px] rounded-full bg-blue-900/10 blur-[120px]" />
- <div className="absolute right-1/4 bottom-0 h-[500px] w-[500px] rounded-full bg-[#b89458]/5 blur-[120px]" />
- </div>
- <div className="site-container relative z-10 pt-16">
- <div className="flex items-center justify-between mb-8">
- <div>
- <h1 className="font-serif text-3xl font-bold text-white">全部领取记录</h1>
- <p className="mt-2 text-sm text-slate-400">追踪您的每一笔资金变动状态</p>
- </div>
- <Link href="/account" className="flex items-center gap-2 rounded-full border border-white/10 bg-white/5 px-5 py-2.5 text-sm font-semibold text-slate-300 transition hover:bg-white/10 hover:text-white backdrop-blur-md">
- <ArrowLeft size={16} /> 返回控制中心
- </Link>
- </div>
- <section className="rounded-[2.5rem] border border-white/10 bg-white/5 p-6 md:p-10 backdrop-blur-2xl shadow-2xl">
- {loading ? <div className="py-20 flex justify-center text-slate-500"><Loader2 className="animate-spin h-8 w-8" /></div> : null}
- {error ? <div className="mb-6 rounded-2xl border border-rose-500/20 bg-rose-500/10 p-4 text-sm text-rose-400">{error}</div> : null}
- {!loading && !error && records.length === 0 ? (
- <div className="py-20 flex flex-col items-center justify-center rounded-[2rem] border border-dashed border-white/10 bg-white/5 text-slate-500">
- <History size={48} className="mb-4 opacity-50" />
- <p className="text-sm">暂无领取记录。</p>
- </div>
- ) : null}
- {!loading && !error && records.length > 0 ? (
- <div className="space-y-4">
- {records.map((w) => (
- <div key={w.serial} className="group rounded-[1.5rem] border border-white/5 bg-white/5 p-6 transition-all hover:bg-white/10">
- <div className="flex flex-col md:flex-row md:items-center justify-between gap-6">
- <div className="flex items-start gap-5">
- <div className="flex h-12 w-12 shrink-0 items-center justify-center rounded-2xl bg-white/5 text-teal-400">
- <History size={22} />
- </div>
- <div>
- <p className="text-base font-bold text-white group-hover:text-teal-400 transition-colors">{w.details}</p>
- <div className="mt-2 flex flex-wrap items-center gap-x-4 gap-y-2 text-xs font-medium text-slate-500">
- <span>流水号: {w.serial}</span>
- <span className="hidden sm:inline">•</span>
- <span>申请: {w.addTime || "-"}</span>
- {w.payTime && <><span className="hidden sm:inline">•</span><span>到账: {w.payTime}</span></>}
- </div>
- </div>
- </div>
- <div className="flex items-center justify-between md:justify-end gap-6 md:border-l md:border-white/5 md:pl-6">
- <div className="text-right">
- <p className="text-xl font-bold text-white tracking-tight">${w.amount}</p>
- <span className={cn("inline-block mt-1.5 rounded-full border px-3 py-1 text-[10px] font-bold uppercase tracking-widest", getStatusStyle(w.status))}>
- {getWithdrawalStatusLabel(w.status)}
- </span>
- </div>
- </div>
- </div>
- </div>
- ))}
- </div>
- ) : null}
- {/* 分页 */}
- {!loading && !error && (hasPrev || hasNext) && (
- <div className="mt-10 flex items-center justify-center gap-4 border-t border-white/5 pt-8">
- <button onClick={() => setPage(p => Math.max(1, p - 1))} disabled={!hasPrev || loading} className="rounded-xl border border-white/10 bg-white/5 px-4 py-2 text-sm font-semibold transition hover:bg-white/10 disabled:opacity-30">上一页</button>
- <span className="text-sm font-medium text-slate-500">第 <span className="text-white">{page}</span> 页</span>
- <button onClick={() => setPage(p => p + 1)} disabled={!hasNext || loading} className="rounded-xl border border-white/10 bg-white/5 px-4 py-2 text-sm font-semibold transition hover:bg-white/10 disabled:opacity-30">下一页</button>
- </div>
- )}
- </section>
- </div>
- </div>
- );
- }
|